﻿using System;
using System.Collections;
using System.Collections.Generic;
using IdentityAtRest.Utility.Identity.Authorization;

namespace IdentityAtRest.Utility.Identity.Authorization
{
    public static class AuthorizationExtensions
    {
        public static bool IsAuthorized(this IList<IAuthorizationDecision> authorizations)
        {
            return IsAuthorizedForAny(authorizations);
        }

        public static bool IsAuthorized(this IList<IAuthorizationDecision> authorizations, string requestedPermission)
        {
            IAuthorizationDecision auth = GetAuthorization(authorizations, requestedPermission);
            if (auth != null)
                return auth.IsAuthorized;
            return false;
        }

        public static bool IsAuthorizedForAll(this IList<IAuthorizationDecision> authorizations)
        {
            if (authorizations == null || authorizations.Count < 1)
                return false;

            foreach (IAuthorizationDecision auth in authorizations)
            {
                if (!auth.IsAuthorized)
                    return false;
            }
            return true;
        }

        public static bool IsAuthorizedForAny(this IList<IAuthorizationDecision> authorizations)
        {
            if (authorizations == null || authorizations.Count < 1)
                return false;

            foreach (IAuthorizationDecision auth in authorizations)
            {
                if (auth.IsAuthorized)
                    return true;
            }
            return false;
        }

        public static IAuthorizationDecision GetAuthorization(this IList<IAuthorizationDecision> authorizations,
                                                              string requestedPermission)
        {
            foreach (IAuthorizationDecision auth in authorizations)
            {
                if (CaseInsensitiveComparer.Default.Compare(auth.Permission, requestedPermission) == 0)
                    return auth;
            }
            return null;
        }

        public static void AddAuthorization(this IList<IAuthorizationDecision> authorizations, IAuthorizationDecision authorizationDecision)
        {
            if (authorizations == null)
                throw new ArgumentNullException("authorizations");
            if (authorizationDecision == null)
                throw new ArgumentNullException("authorizationDecision");

            authorizations.Add(authorizationDecision);
        }

        public static IAuthorizationDecision AddAuthorization(this IList<IAuthorizationDecision> authorizations, string permission,
                                                              bool isAuthorized)
        {
            return AddAuthorization(authorizations, permission, isAuthorized, "");
        }

        public static IAuthorizationDecision AddAuthorization(this IList<IAuthorizationDecision> authorizations, string permission,
                                                              bool isAuthorized, string explanation)
        {
            var auth = new AuthorizationDecision(permission, isAuthorized, explanation);
            AddAuthorization(authorizations, auth);
            return auth;
        }
    }
}